﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Aspose.Words;
using AntsCode.WordsExtensions;

namespace AntsCode.WordsExtensions
{
    public partial class Form1 : Form
    {
        private Document Doc;
        private AdvancedMailMerge MailMerge;

        public Form1()
        {
            InitializeComponent();

            this.InputFileName.Text = Path.Combine(Application.StartupPath, "Test.doc");
            this.OutputFileName.Text = Path.Combine(Application.StartupPath, "Out.pdf");
        }

        private void LoadButton_Click(object sender, EventArgs e)
        {
            this.Doc = new Document(this.InputFileName.Text);

            this.MailMerge = new AdvancedMailMerge();

             // Set region data
            this.MailMerge.DocumentData = GetOrderData();
            this.MailMerge.AddRegionData(GetOrderGroups(), "OrderGroups", "OrderGroupId", null);
            this.MailMerge.AddRegionData(GetOrderDeliveryTimes(), "OrderDeliveryTimes",
                "OrderDeliveryTimeId", "OrderGroupId");
            this.MailMerge.AddRegionData(GetOrderItems(), "OrderItems", "OrderItemId",
                "OrderDeliveryTimeId");
            this.MailMerge.AddRegionData(GetPackItems(), "PackItems", "PackItemId", "OrderItemId");

            // Add a MergeField event
            this.MailMerge.MergeField += FormatNotes;

            // Load the document
            this.MailMerge.Load(this.Doc);

            // Clear any existing list items
            this.ErrorList.Items.Clear();
            RegionTreeView.Nodes.Clear();

            foreach (MergeError error in this.MailMerge.Errors)
            {
                this.ErrorList.Items.Add(error.Description);
            }

            if (this.MailMerge.Regions != null)
            {
                // Being recursive function to add regions to the tree view
                this.AddRegionsToList(RegionTreeView.Nodes, this.MailMerge.Regions);

                RegionTreeView.ExpandAll();
            }

            if (this.MailMerge.Errors.Count() == 0)
            {
                this.MergeButton.Enabled = true;
            }
            else
            {
                this.MergeButton.Enabled = false;
            }
        }

        private void FormatNotes(object sender, MergeFieldEventArgs e)
        {
            // Ensure all notes end in a full stop
            if (e.FieldName == "Notes" && (!String.IsNullOrEmpty(e.Text) && !e.Text.EndsWith(".")))
            {
                e.Text += "."; 
            }
        }

        private void AddRegionsToList(TreeNodeCollection collection, IEnumerable<MergeRegion> regions)
        {
            TreeNode node;

            foreach (MergeRegion region in regions)
            {
                node = collection.Add(region.Name);

                if (region.ChildRegions != null)
                {
                    this.AddRegionsToList(node.Nodes, region.ChildRegions);
                }
            }
        }

        private void MergeButton_Click(object sender, EventArgs e)
        {
            this.MailMerge.Merge();

            // Save the document to the output file
            this.Doc.Save(this.OutputFileName.Text);

            this.MergeButton.Enabled = false;
        }

        private DataRow GetOrderData()
        {
            DataTable table = new DataTable("OrderGroups");

            table.Columns.Add("OrderId", typeof(int));
            table.Columns.Add("DeliveryAddress");
            table.Columns.Add("DeliverySuburb");
            table.Columns.Add("DeliveryPostcode");
            table.Columns.Add("InvoiceAddress");
            table.Columns.Add("InvoiceSuburb");
            table.Columns.Add("InvoicePostcode");

            table.Rows.Add(1, "2 Queen St", "Melbourne", "3000", "2 Queen St", "Melbourne", "3000");

            return table.Rows[0];
        }

        private DataTable GetOrderGroups()
        {
            DataTable table = new DataTable("OrderGroups");

            table.Columns.Add("OrderGroupId", typeof(int));
            table.Columns.Add("Title");

            table.Rows.Add(1, "Food");
            table.Rows.Add(2, "Equipment");

            return table;
        }

        private DataTable GetOrderDeliveryTimes()
        {
            DataTable table = new DataTable("OrderDeliveryTimes");

            table.Columns.Add("OrderDeliveryTimeId", typeof(int));
            table.Columns.Add("OrderGroupId", typeof(int));
            table.Columns.Add("Time");

            table.Rows.Add(1, 1, "10.00am");
            table.Rows.Add(2, 1, "12.30pm");
            table.Rows.Add(3, 2, "10.00am");
            table.Rows.Add(4, 2, "12.30pm");

            return table;
        }

        private DataTable GetOrderItems()
        {
            DataTable table = new DataTable("OrderItems");

            table.Columns.Add("OrderItemId", typeof(int));
            table.Columns.Add("OrderDeliveryTimeId", typeof(int));
            table.Columns.Add("ItemTitle");
            table.Columns.Add("Notes");
            table.Columns.Add("Quantity");
            table.Columns.Add("Taxable", typeof(bool));

            table.Rows.Add(1, 1, "Bagel", "With cream cheese", 12, true);
            table.Rows.Add(2, 1, "Fruit Juice", "Orange & Pineapple", 8, false);
            table.Rows.Add(3, 2, "Lunch Pack", "", 15, true);
            table.Rows.Add(4, 2, "Fruit & Cheese Platter", "", 3, false);
            table.Rows.Add(5, 3, "Napkins", "Linen", 15, true);
            table.Rows.Add(5, 4, "Cutlery", "Silver", 15, true);
            table.Rows.Add(5, 4, "Plates", "Ceramic", 15, true);

            return table;
        }

        private DataTable GetPackItems()
        {
            DataTable table = new DataTable("PackItems");

            table.Columns.Add("PackItemId", typeof(int));
            table.Columns.Add("OrderItemId", typeof(int));
            table.Columns.Add("ItemTitle");
            table.Columns.Add("Notes");
            table.Columns.Add("Quantity");

            table.Rows.Add(1, 3, "Sandwich", "White & Wholemeal mix", 15);
            table.Rows.Add(2, 3, "Fruit", "Apples & Oranges", 15);

            return table;
        }
    }
}
